﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;

namespace AdAggregator.Util
{
    public static class StringUtils
    {
        public static string ToLatinString(this String text)
        {
            var returnedText = text;
            var charMapping = new Dictionary<string, string>
                {
                    {"ą", "a"},{"ć", "c"},{"ę", "e"},{"ł", "l"},{"ń", "n"},{"ó", "o"},{"ś", "s"},{"ź", "z"},{"ż", "z"},
                    {"Ą", "A"},{"Ć", "C"},{"Ę", "E"},{"Ł", "L"},{"Ń", "N"},{"Ó", "O"},{"Ś", "S"},{"Ź", "Z"},{"Ż", "Z"}
                };
            foreach (var mapping in charMapping)
            {
                returnedText = returnedText.Replace(mapping.Key, mapping.Value);
            }
            return returnedText;
        }

        public static string RemoveWhitespaces(this String text)
        {
            return Regex.Replace(text, @"\s+", "");
        }

        public static string FormatAsNumberWithSpaces(this String text)
        {
            var format = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone();
            format.NumberGroupSeparator = " ";
            double number;
            var formattedText = text;
            if (double.TryParse(text, out number))
            {
                formattedText = number.ToString("n", format);
                if (formattedText.Contains("."))
                {
                    formattedText = formattedText.TrimEnd('0');
                    if (formattedText.EndsWith("."))
                        formattedText = formattedText.Replace(".", "");
                }
            }
            return formattedText;
        }

        public static string RemoveFromTheIndex(this string str, int idx)
        {
            if (idx > -1)
            {
                return str.Substring(0, idx);
            }
            return str;
        }

        public static string RemoveLastAtTheEnd(this string str, string toRemove)
        {
            var idx = str.LastIndexOf(toRemove);
            return str.RemoveFromTheIndex(idx);
        }

        public static string RemoveFirstAtTheEnd(this string str, string toRemove)
        {
            var idx = str.IndexOf(toRemove);
            return str.RemoveFromTheIndex(idx);
        }

        public static string RemoveFirstAtTheBeginning(this string str, string toRemove)
        {
            var idx = str.IndexOf(toRemove);
            if (idx == -1) return str;
            return str.Substring(idx + toRemove.Length);
        }

        public static string RemoveNonDigits(this string text)
        {
            return Regex.Replace(text, "[^0-9]", "");
        }

        private static readonly Dictionary<char, int> RomanDictionary = new Dictionary<char, int>
                                                                            {
                                                                                {'I', 1},
                                                                                {'V', 5},
                                                                                {'X', 10},
                                                                                {'L', 50},
                                                                                {'C', 100},
                                                                                {'D', 500},
                                                                                {'M', 1000}
                                                                            };
        //
        // method acquired from http://rosettacode.org/wiki/Roman_numerals/Decode
        //
        public static int DecodeRomanNumber(string roman)
        {
            /* Make the input string upper-case,
             * because the dictionary doesn't support lower-case characters. */
            roman = roman.ToUpper();

            /* total = the current total value that will be returned.
             * minus = value to subtract from next numeral. */
            int total = 0, minus = 0;

            for (int i = 0; i < roman.Length; i++) // Iterate through characters.
            {
                // Get the value for the current numeral. Takes subtraction into account.
                int thisNumeral = RomanDictionary[roman[i]] - minus;

                /* Checks if this is the last character in the string, or if the current numeral
                 * is greater than or equal to the next numeral. If so, we will reset our minus
                 * variable and add the current numeral to the total value. Otherwise, we will
                 * subtract the current numeral from the next numeral, and continue. */
                if (i >= roman.Length - 1 ||
                    thisNumeral + minus >= RomanDictionary[roman[i + 1]])
                {
                    total += thisNumeral;
                    minus = 0;
                }
                else
                {
                    minus = thisNumeral;
                }
            }

            return total; // Return the total.
        }
    }
}